/* 四人小队基本行为 */

import { isInArray } from "@/utils";
import { crossConst, leftConst, rightConst, squardDirection, tactical } from "./constant";
import { squardGetPosCreep, squardGetRoomPosition, squardHealDirection, squardPosDirection } from "./state";

/* 小队战术动作 斜插 */
export function squardCross(squardData:Squard):void{
    for (var cName in squardData)
    {
        if (Game.creeps[cName] && Game.creeps[cName].fatigue) return
    }
    for (var cName in squardData)
    {
        if (!Game.creeps[cName]) continue
        Game.creeps[cName].move(squardDirection[crossConst[squardData[cName].position]])
        squardData[cName].position = tactical['cross'][squardData[cName].position] as '↘' | '↗' | '↖' | '↙'

    }
}

/* 小队战术动作 右转 */
export function squardRight(squardData:Squard):void{
    for (var cName in squardData)
    {
        if (Game.creeps[cName] && Game.creeps[cName].fatigue) return
    }
    for (var cName in squardData)
    {
        if (!Game.creeps[cName]) continue
        Game.creeps[cName].move(squardDirection[rightConst[squardData[cName].position]])
        squardData[cName].position = tactical['right'][squardData[cName].position] as '↘' | '↗' | '↖' | '↙'
    }
}

/* 小队战术动作 左转 */
export function squardLeft(squardData:Squard):void{
    for (var cName in squardData)
    {
        if (Game.creeps[cName] && Game.creeps[cName].fatigue) return
    }
    for (var cName in squardData)
    {
        if (!Game.creeps[cName]) continue
        Game.creeps[cName].move(squardDirection[leftConst[squardData[cName].position]])
        squardData[cName].position = tactical['left'][squardData[cName].position] as '↘' | '↗' | '↖' | '↙'
    }
}

/* 进入目标房间前使用  治疗爬方向朝向目标房间的入口 */
export function initSquard(thisRoom:string,disRoom:string,squardData:Squard):void{
    var Healdirection = squardHealDirection(squardData)
    if (Healdirection == null)
    {
        return
    }
    else if (Healdirection == '←')
    {
        switch (Game.rooms[thisRoom].findExitTo(disRoom))
        {
            case FIND_EXIT_LEFT:{break;}
            case FIND_EXIT_RIGHT:{squardCross(squardData);break}
            case FIND_EXIT_BOTTOM:{squardLeft(squardData);break}
            case FIND_EXIT_TOP:{squardRight(squardData);break}
        }
    }
    else if (Healdirection == '→')
    {
        switch (Game.rooms[thisRoom].findExitTo(disRoom))
        {
            case FIND_EXIT_LEFT:{squardCross(squardData);break;}
            case FIND_EXIT_RIGHT:{break;}
            case FIND_EXIT_BOTTOM:{squardRight(squardData);break}
            case FIND_EXIT_TOP:{squardLeft(squardData);break}
        }
    }
    else if (Healdirection == '↑')
    {
        switch (Game.rooms[thisRoom].findExitTo(disRoom))
        {
            case FIND_EXIT_LEFT:{squardLeft(squardData);break}
            case FIND_EXIT_RIGHT:{squardRight(squardData);break}
            case FIND_EXIT_BOTTOM:{squardCross(squardData);break}
            case FIND_EXIT_TOP:{break}
        }
    }
    else if (Healdirection == '↓')
    {
        switch (Game.rooms[thisRoom].findExitTo(disRoom))
        {
            case FIND_EXIT_LEFT:{squardRight(squardData);break}
            case FIND_EXIT_RIGHT:{squardLeft(squardData);break}
            case FIND_EXIT_BOTTOM:{break}
            case FIND_EXIT_TOP:{squardCross(squardData);break}
        }
    }
    return
}

/* 根据小队攻击爬的方向和目标方向进行战术动作 使得攻击爬方向朝向目标方向 */
export function squardAttackOrient(Attackdirection:string,direction_:string,squardData:Squard):void{
    /* 根据自己的方向进行旋转 */
    if (Attackdirection == '←')
    {
        switch(direction_)
        {
            case '←':{break;}
            case '→':{squardCross(squardData);break}
            case '↓':{squardLeft(squardData);break}
            case '↑':{squardRight(squardData);break}
        }
    }
    else if (Attackdirection == '→')
    {
        switch(direction_)
        {
            case '←':{squardCross(squardData);break;}
            case '→':{break;}
            case '↓':{squardRight(squardData);break}
            case '↑':{squardLeft(squardData);break}
        }
    }
    else if(Attackdirection == '↑')
    {
        switch(direction_)
        {
            case '←':{squardLeft(squardData);break}
            case '→':{squardRight(squardData);break}
            case '↓':{squardCross(squardData);break}
            case '↑':{break}
        }
    }
    else if (Attackdirection == '↓')
    {
        switch(direction_)
        {
            case '←':{squardRight(squardData);break}
            case '→':{squardLeft(squardData);break}
            case '↓':{break}
            case '↑':{squardCross(squardData);break}
        }
    }
}

/* 小队所有队员各就各位 */
export function squardSteady(squardData:Squard):void{
    for (var i in squardData)
    {
        if (!Game.creeps[i]) continue
        var disPos = squardGetRoomPosition(squardData,squardData[i].position)
        /* 用不同的移动方式防止各种bug */
        if (Game.time % 3)Game.creeps[i].moveTo(disPos)
        else Game.creeps[i].goTo(disPos,0)
    }
}

/* 小队寻找旗帜 */
export function squardColorFlagRange(squardData:Squard,color:ColorConstant):Flag{
    /* 先寻找小队左上角的坐标 */
    var standedCreep = squardGetPosCreep(squardData,'↖')
    if (!standedCreep) return null
    var disFlag = standedCreep.pos.findClosestByRange(FIND_FLAGS,{filter:(flag)=>{
        return flag.color == color
    }})
    if (disFlag) return disFlag
    return null
}

/* 小队治疗爬行为 */
export function squardXRaction(squardData:Squard):void{
    for (var i in squardData)
    {
        var creep = Game.creeps[i]
        if (!creep) continue
        /* 治疗类型爬 */
        if (creep.memory.creepType == 'heal')
        {
            /* 寻找小队内血量最少的爬 */
            var woundCreep:Creep
            for (var wc in squardData)
            {
                if ( Game.creeps[wc] && !woundCreep && Game.creeps[wc].hits < Game.creeps[wc].hitsMax)
                woundCreep = Game.creeps[wc]
                if (Game.creeps[wc] && woundCreep)
                {
                    if (Game.creeps[wc].hits < woundCreep.hits) woundCreep =  Game.creeps[wc]
                }  
            }
            if (woundCreep)
            creep.heal(woundCreep)
            else
            /* 如果奶量都满的,就奶攻击爬 */
            {
                var index = squardData[i].index
                var disIndex:number
                if (index == 1) disIndex = 0
                else if (index ==3) disIndex = 2
                else disIndex = index
                var disCreep:Creep
                for (var Index in squardData)
                {
                    if (squardData[Index].index == disIndex && Game.creeps[Index])
                    disCreep = Game.creeps[Index]
                }
                if (!disCreep) disCreep = creep
                creep.heal(disCreep)
            }

            /* 如果有攻击部件，攻击附近血量最少的爬 */
            if (creep.getActiveBodyparts('ranged_attack') > 0)
            {
                var enemy = creep.pos.findInRange(FIND_HOSTILE_CREEPS,3,{filter:(creep_)=>{
                    return !isInArray(Memory.whitesheets,creep_.owner.username) && !creep_.pos.GetStructure('rampart')
                }})
                var enemyCreep:Creep
                if (enemy.length == 0)
                {
                    enemyCreep = enemy[0]
                }
                else if (enemy.length > 1)
                {
                    for (var ec of enemy)
                    {
                        if (!enemyCreep) enemyCreep = ec
                        else
                        {
                            if (ec.hits < enemyCreep.hits)
                            enemyCreep = ec
                        }
                    }
                }
                if (enemyCreep){
                    creep.rangedAttack(enemyCreep)
                }
                else
                    creep.rangedMassAttack()
            }
        }
        /* 攻击类型的爬也有可能携带heal部件 */
        else if (creep.memory.creepType == 'attack')
        {
            /* 治疗自己 */
            if (creep.getActiveBodyparts('heal') > 0 && creep.hits < creep.hitsMax)
            creep.heal(creep)
                        /* 如果有攻击部件，攻击附近血量最少的爬 */
                if (creep.getActiveBodyparts('ranged_attack') > 0)
                        {
                            var enemy = creep.pos.findInRange(FIND_HOSTILE_CREEPS,3,{filter:(creep_)=>{
                                return !isInArray(Memory.whitesheets,creep_.owner.username) && !creep_.pos.GetStructure('rampart')
                            }})
                            var enemyCreep:Creep = null
                            if (enemy.length == 1)
                            {
                                enemyCreep = enemy[0]
                            }
                            else if (enemy.length > 1)
                            {
                                for (var ec of enemy)
                                {
                                    if (!enemyCreep) enemyCreep = ec
                                    else
                                    {
                                        if (ec.hits < enemyCreep.hits)
                                        enemyCreep = ec
                                    }
                                }
                            }
                            if (enemyCreep){
                                
                                creep.rangedAttack(enemyCreep)
                            }
                            else
                                creep.rangedMassAttack()
                        }
        }
    }
}